package uy.com.tsi2G7.superbet.integration.betfair;

import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;

import uy.com.tsi2G7.superbet.account.InsufficientFoundException;
import uy.com.tsi2G7.superbet.account.dao.AccountNotFoundException;
import uy.com.tsi2G7.superbet.bet.Bet;
import uy.com.tsi2G7.superbet.bet.BetService;
import uy.com.tsi2G7.superbet.event.EventMarketResult;
import uy.com.tsi2G7.superbet.event.EventSource;
import uy.com.tsi2G7.superbet.integration.betfair.rss.Feed;
import uy.com.tsi2G7.superbet.integration.betfair.rss.FeedMessage;
import uy.com.tsi2G7.superbet.integration.betfair.rss.RSSFeedParser;
import uy.com.tsi2G7.superbet.ui.BetHistoryDescriptor;
import uy.com.tsi2G7.superbet.user.UserNotificationException;

public class BetFairProfitsConsumer extends QuartzJobBean{
	
	private HibernateTemplate hibernateTemplate;
	private BetService betService;
	
	@Override
	protected void executeInternal(JobExecutionContext jobExecutionContext)
			throws JobExecutionException {
		JobDataMap map = jobExecutionContext.getJobDetail().getJobDataMap();

		hibernateTemplate = (HibernateTemplate) map.get("hibernateTemplate");
		betService=(BetService) map.get("betService");
		loadProfitsAndLoss();
	}
	
	
	protected HibernateTemplate getHibernateTemplate(){
		if(hibernateTemplate==null)
			hibernateTemplate=(HibernateTemplate) new FileSystemXmlApplicationContext("test/context.xml").getBean("hibernateTemplate");
		return hibernateTemplate;
	}
	
	public static void main(String[] args) {
		BetFairProfitsConsumer main = new BetFairProfitsConsumer();
		main.loadProfitsAndLoss();
	}

	private void loadProfitsAndLoss() {
		
		try {
			List<EventMarketResult> results = getHibernateTemplate().find(
					"select res from EventMarket m, EventMarketResult res, SimpleBet b where res.source=? and  res.marketId=b.marketId and res.marketId=m.marketId and res.winAmount<0 and m.startDate < ?",new Object[]{EventSource.BETFAIR,new Date()});
			
			Map<String, List<EventMarketResult>> resultsByEventTypeId = new HashMap<String, List<EventMarketResult>>();
			for (EventMarketResult res : results) {
				if(!resultsByEventTypeId.containsKey(buildKey(res)))
					resultsByEventTypeId.put(String.valueOf(buildKey(res)),new ArrayList<EventMarketResult>());
				resultsByEventTypeId.get(String.valueOf(buildKey(res))).add(res);
			}
			
			
			//TODO hacerlo transaccional
			for (String key : resultsByEventTypeId.keySet()) {
				
					RSSFeedParser parser = new RSSFeedParser(
							"http://rss.betfair.com/RSS.aspx?format=rss&sportID="+getEventTypeFromKey(key)+"&marketID="+getMarketFromKey(key));
					Feed feed = parser.readFeed();
					if(feed!=null&&feed.getEntries()!=null)
						for (FeedMessage message : feed.getEntries()) {
							for (EventMarketResult res : resultsByEventTypeId.get(key)) {
								if(message.getLink().indexOf("marketID="+res.getMarketId())>0){
									System.out.println(message.getLink());
									System.out.println(message.getTitle());
									System.out.println(message.getDescription());
									System.out.println("res: "+res.getName());
									if(res.getName().toUpperCase().indexOf(message.getDescription().substring(message.getDescription().indexOf(":")+1).toUpperCase().trim())>0)
										res.setWinAmount(res.getAmount());
									else
										res.setWinAmount(BigDecimal.ZERO);
									getHibernateTemplate().merge(res);
								}
							}
							getBetService().fireEventFinished(Long.valueOf(getEventTypeFromKey(key)),Long.valueOf(getMarketFromKey(key)));
						}
			}
			
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	private String buildKey(EventMarketResult res) {
		return String.valueOf(res.getEventTypeId())+"/"+String.valueOf(res.getMarketId());
	}
	
	private String getEventTypeFromKey(String key) {
		return StringUtils.split(key,"/")[0];
	}
	
	private String getMarketFromKey(String key) {
		return StringUtils.split(key,"/")[1];
	}

	public BetService getBetService() {
		if(betService==null)
			betService=new BetService() {
				@Override
				public List<BetHistoryDescriptor> getlastUserSimpleBetsDescription(
						String userId) {
					return null;
				}
				
				@Override
				public void doSimpleBet(String userId, long eventTypeId, long eventId,
						long marketId, long marketResultId, BigDecimal amount)
						throws RemoteException, AccountNotFoundException,
						InsufficientFoundException {
				}

				@Override
				public void fireEventFinished(long eventTypeId, long marketId)
						throws RemoteException, AccountNotFoundException {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void doBet(Bet bet) throws RemoteException,
						AccountNotFoundException, InsufficientFoundException {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void updateResultAndBets(long market, long result)
						throws RemoteException, AccountNotFoundException,
						UserNotificationException {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void doUserBet(String userId, long eventTypeId, long eventId, long marketId,
						long marketResultId, BigDecimal amount, boolean result) throws RemoteException,
						AccountNotFoundException, InsufficientFoundException {
					// TODO Auto-generated method stub
					
				}

				@Override
				public List<BetHistoryDescriptor> getPendingUserBetsDescription(String user) {
					// TODO Auto-generated method stub
					return null;
				}

				@Override
				public Bet confirmUserBet(String userId, long marketId, long marketResultId) throws RemoteException,
						AccountNotFoundException, InsufficientFoundException {
					// TODO Auto-generated method stub
					return null;
				}
			};
		return betService;
	}
	

}
